<?php
namespace com;

class FFmpeg{
    /*
     * 文件路径
     */
	private $file;
    /*
     * 配置信息
     */	
    private $config;
    /**
     * 转码开始构造方法
     * @param array  $file   文件路径
     * @param array  $config 配置信息
     */
    public function __construct($file,$config){
        $this->file   = $file;
		$this->path   = pathinfo($file)['dirname'];
		$this->name   = pathinfo($file)['filename'];
        $this->config = $config;
		ini_set('max_execution_time','0');
    }
	
    public function create(){
		//获取视频文件信息
		$metadata=json_decode(shell_exec("ffprobe -i ".$this->file."  -v quiet  -print_format json -show_streams -show_format -select_streams v:0"),true);
		if($metadata){
			if($this->config['screen']){
				$screen = explode(",",$this->config['screen']);
				foreach($screen as $k => $v){
		           $this->setvideo($metadata,$v,'_'.$v);
				}
          	}else{
				   $this->setvideo($metadata,$this->config['hd']);
			}	   
		}		
	}
    private function setvideo($metadata,$hd,$screen=''){
        $watermark = $this->config['watermark'];
        $hd = intval($hd*1);
        $wd = 0;
        $videometa = $metadata['format'];
        $videostreams = $metadata['streams'];
        $bitrate = floor($videometa['bit_rate'] / 1000);
        $size = "";
        $bv = 500;
        $bufsize = 1000;
        $maxrate = 500;
        $videooriginH = 0;
        $videooriginW = "";
        $audiooriginC = "";
        $tsjiami = $this->config['tsjiami'];	
        if($hd==480) {
            $wd = 720;	
            $bv = 500;
            $bufsize = 1000;
            $maxrate = 500;			
        }else if ($hd==720) {
            $wd = 1280;
            $bv = 720;
            $bufsize = 2000;
            $maxrate = 1000;			
        }else if ($hd==1080){
            $wd = 1920;
            $bv = 2000;
            $bufsize = 4000;
            $maxrate = 2000;				
        }else{
            for($i = 0; $i < count($videostreams); $i++) {
                $hd = $videostreams[$i]['height'];
                $wd = $videostreams[$i]['width'];
                break;
            }			
        }
        if($bitrate > 2000){
            $bv = 2000;
            $maxrate = $bv;
            $bufsize = 2*$bv;
        }
        if($bitrate < 500){
            $bv = $bitrate;
            $maxrate = $bv;
            $bufsize = 2*$bv;
        }		
        for($i = 0; $i < count($videostreams); $i++) {
            if ($videostreams[$i]['codec_type'] == 'video') {
                if ($videostreams[$i]['height'] <= $hd) {
                        $hd = $videostreams[$i]['height'];
                }
                if ($videostreams[$i]['width'] <= $wd){
                        $wd = $videostreams[$i]['width'];
                }
                $videooriginH = $videostreams[$i]['height'];
				$videooriginW = $videostreams[$i]['width'];
                $videooriginC = $videostreams[$i]['codec_name'];
                break;
            }
        }
        for($i = 0; $i < count($videostreams); $i++) {
            if ($videostreams[$i]['codec_type'] == 'audio') {
                    $audiooriginC = $videostreams[$i]['codec_name'];
                    break;
            }
        }
        $size = $wd."x".$hd;
        $config=[
                '-s '.$size,
                '-b:v '.$bv."k",
                '-vcodec libx264',
                '-acodec aac',
                '-ac 2',
                '-b:a 128k',
                '-bufsize '.$bufsize."k",
                '-maxrate '.$maxrate."k",
                '-q:v 6',
                '-strict -2',
				"-pix_fmt yuv420p",
				"-movflags faststart",
                '-start_number 0',
                '-hls_time 10',
                '-hls_list_size 0',
                '-f hls'
		];
        if($tsjiami){
			    $myfile = fopen($this->path."/key.info", "w");
			    fwrite($myfile,"http://newcn.zanpiancms.com/uploads/movies/ts.key\n".$this->path."/ts.key");
				$myfile = fopen($this->path."/ts.key", "w");
				fwrite($myfile,$this->randomkey());
                $jiamiconfig = '-hls_key_info_file '.$this->path.'/key.info';
				array_push($config,$jiamiconfig);	
        }		
		$vf=$this->vf();
		//$vf = 'drawtext="fontfile=msyh.ttf:text="'.$txt.'":fontcolor=white@1.0:fontsize=24:y=10:x=w-tw-w/10*mod(t\,30):enable=gt(mod(t\,20)\,10)"';	
		//是否开启秒切
        if($this->config['miaoqie']){
			//设置的高度与视频高度匹配并且为标准的MP4文件
            if ($videooriginH <= $hd*1 && $videooriginC == "h264" || $audiooriginC == "aac"){
				//判断增加水印
                if($vf || $screen){
                    $this->tranchunk($vf,$config,$screen);
                }else{
					//不需要增加水印直接切片
                    $this->transcoding($tsjiami,$screen);
                }
            }else{
                $this->tranchunk($vf,$config,$screen);
            }
        }else{
               $this->tranchunk($vf,$config,$screen);
        }			
		
	}


	private function tranchunk($vf,$config,$screen=''){
		array_unshift($config,'ffmpeg','-i',$this->file);
		if($vf){
		    array_push($config,'-vf',$vf);	
		}
		array_push($config,$this->path.'/index'.$screen.'.m3u8');
		$cmd=implode(" ",$config);
		$this->execInBackground($cmd);
		//$this->modproc($cmd);
		//print_r($cmd);
	    //exec($cmd." 2>&1 ;");
	}
	private function transcoding($tsjiami,$screen=''){
		$config=[
        '-c copy',
        '-bsf:v h264_mp4toannexb',
        '-hls_time 10',
        '-strict -2',
        '-start_number 0',
        '-hls_list_size 0'
        ];
		array_unshift($config,'ffmpeg','-i',$this->file);
		if($tsjiami){
           array_push($config,'-hls_key_info_file '.$this->path.'/key.info');
        }
		array_push($config,$this->path.'/index'.$screen.'.m3u8');
		$cmd=implode(" ",$config);
		//print_r($cmd);
		//return shell_exec($cmd);
		;
		print_r($this->execInBackground($cmd));
		//$this->modproc($cmd);
	}
	private function vf(){
		//$srt=$this->path.'/'.$this->name.'.srt';
		//if($this->config['watermark']){
		//	$vf[0]='movie=' + wmimage + ' [watermark]; [in][watermark] overlay=main_w-overlay_w [out]';
		//}
		//if(file_exists($srt)){
		//	$vf[1]='subtitles='.$srt;
		//}
		if($this->config['stream_txt']){
			
		$txt=mb_convert_encoding($this->config['stream_txt'],'GBK');
		if($this->config['stream_position']==2){
		    $y='h-line_h-10';
		}else{
		    $y=	'10';
		}
		    $vf[2]= 'drawtext="fontfile=msyh.ttf:text="'.$txt.'":fontcolor=white@1.0:fontsize="'.$this->config['stream_size'].'":y="'.$y.'":x=w-tw-w/"'.$this->config['stream_last'].'"*mod(t\,"'.$this->config['stream_interval'].'"):enable=gt(mod(t\,20)\,10)"';
		}
		if($vf){
			return implode(" ",$vf);
		}else{
			return false;
		}

	}
	public function screenshots(){
	   $cmd="ffmpeg -ss 00:00  -i ".$this->file." -f image2 -y -r 0.2 -t 02:45 ".$this->path."/screenshots-%03d.jpg";
	   $this->execInBackground($cmd);
	}	
	public function thumbnail(){
	   $cmd="ffmpeg -ss 00:01:06 -i ".$this->file." -f image2 -y -s 352x240 ".$this->path."/thumbnail.jpg";
	   $this->execInBackground($cmd);
	}
	public function gif(){
	   $cmd="ffmpeg -i ".$this->file." -vframes 30 -y -f gif -s 352x240 ".$this->path."/a.gif";
	   $this->execInBackground($cmd);		
	}
    private function randomkey() {
        $data = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f","g","A","B","C","D","E","F","G"];
        for ($j = 0; $j < 500; $j++) {
            $result = "";
            for ($i = 0; $i < 16; $i++) {
                $r = floor($this->randFloat() * count($data));

                $result.= $data[$r];
            }
            return $result;
        }
    }
    private function randFloat($min=0, $max=1){
        return $min + mt_rand()/mt_getrandmax() * ($max-$min);
    }	
    private function modproc($cmd) {
	    $cmd = str_replace(" ;", " 2>&1 ;", $cmd." ;")." 2>&1";
	    $nl = "=========================================================\n";
	    echo "\n".$nl."Command:\n".$nl.$cmd."\n\n";
	    exec($cmd,$out);
	    foreach($out as $outd){
		    $outs .= $outd."\n";
	    }
	    echo "Output:\n".$outs."\n\n";
    }
    function execInBackground($cmd){ 
    if(substr(php_uname(),0,7) == "Windows"){ 
        $pid=pclose(popen("start /B ". $cmd, "w"));
    } 
    else{ 
        exec($cmd . " > /dev/null &");   
    }
	
   } 	

}
